#ifndef EDGE_STOPPING_GLSL
#define EDGE_STOPPING_GLSL

#define DEPTH_FACTOR 0.5

float NormalEdgeStoppingWeight(vec3 centerNormal, vec3 sampleNormal, float power)
{
    return pow(clamp(dot(centerNormal, sampleNormal), 0.0f, 1.0f), power);
}



float DepthEdgeStoppingWeight(float centerDepth, float sampleDepth, float phi)
{
    return exp(-abs(centerDepth - sampleDepth) / phi);
}



float LumaEdgeStoppingWeight(float centerLuma, float sampleLuma, float phi)
{
    return abs(centerLuma - sampleLuma) / phi;
}



float ComputeEdgeStoppingWeight(
                      float centerDepth,
                      float sampleDepth,
                      float phiDepth
                    #if defined(USE_EDGE_STOPPING_NORMAL_WEIGHT)
                    , vec3  centerNormal,
                      vec3  sampleNormal,
                      float phiNormal
                    #endif
                    #if defined(USE_EDGE_STOPPING_LUMA_WEIGHT)
                    , float centerLuma,
                      float sampleLuma,
                      float phiLuma
                    #endif
)
{
    const float wZ = DepthEdgeStoppingWeight(centerDepth, sampleDepth, phiDepth);
#if defined(USE_EDGE_STOPPING_NORMAL_WEIGHT)    
    const float wNormal = NormalEdgeStoppingWeight(centerNormal, sampleNormal, phiNormal);
#else
    const float wNormal = 1.0f;
#endif    
#if defined(USE_EDGE_STOPPING_LUMA_WEIGHT)
    const float wL = LumaEdgeStoppingWeight(centerLuma, sampleLuma, phiLuma);
#else 
    const float wL = 1.0f;
#endif

    const float w = exp(0.0 - max(wL, 0.0) - max(wZ, 0.0)) * wNormal;

    return w;
}



#endif